# coding=utf-8
# encoding=utf-8

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import *
from DataBase.Connect import session
import urllib.request
import xmlDecoder
import time
import ConfigHelper as config

# Model基类,创建了一个BaseModel类,这个类的子类可以自动与一个表关联
Base = declarative_base()
# 这样设置以后直接可以通过model类进行query查询,否则必须通过session进行查询。
Base.query = session.query_property()


# 定义数据库类
class ACStatus(Base):
    # 表的名字
    __tablename__ = 'Status_Tabel'
    # 表的结构
    DeviceAddress = Column(String(20), primary_key=True)
    ATemp = Column(String(20))
    Aoc = Column(String(20))
    Dwind = Column(String(20))
    FModel = Column(String(20))
    HElec = Column(String(20))
    ErrorMessage = Column(String(20))
    Updatetime = Column(String(20))
    Aoctime = Column(String(20))
    eTemp = Column(String(20))

    def __str__(self):
        pass

    def __init__(self,
                 DeviceAddress=1, ATemp=None, Aoc=None,
                 Dwind=None, FModel=None, HElec=None, ErrorMessage=None,
                 Updatetime=None, Aoctime=None, eTemp=None
                 ):
        self.ATemp = ATemp
        self.DeviceAddress = DeviceAddress
        self.Aoc = Aoc
        self.Dwind = Dwind
        self.FModel = FModel
        self.HElec = HElec
        self.Updatetime = Updatetime
        self.ErrorMessage = ErrorMessage
        self.Aoctime = Aoctime
        self.eTemp = eTemp

    def get_ac_status(self):
        """
        获取空调当前状态
        1.根据当前address，发送请求获取包含当前状态信息的xml字符串
        2.根据返回的xml字符串解码成对应类并返回
        :return: 
        """
        url = "http://" + config.getConfig(section='address', key='gateWayIp') + "/ctrl.xml?"
        add = "u=" + str(self.DeviceAddress)
        req = urllib.request.Request(url=url+add)
        res = urllib.request.urlopen(req)
        res = res.read()
        statusData = str(xmlDecoder.get_xml_ret(res, 'ret')).split(',')
        self.ac_status_decoder(statusData[0:82], statusData[131:134])
        self.Updatetime = time.strftime("%Y/%m/%d %H:%M:%S", time.localtime())
        return self

    def ac_status_decoder(self, coilsDataList, inpRegDataList):
        self.Aoc = "开机"
        self.HElec = "无"
        self.ErrorMessage = "无"
        self.FModel = "送风"
        self.Dwind = "高风"
        if coilsDataList[7] == '1':
            self.Aoc = "开机"
        else:
            self.Aoc = "关机"

        if coilsDataList[0] == '1':
            self.FModel = "送风"
        if coilsDataList[1] == '1':
            self.FModel = "除湿"
        if coilsDataList[2] == '1':
            self.FModel = "制热"
        if coilsDataList[3] == '1':
            self.FModel = "制冷"
        if coilsDataList[4] == '1':
            self.FModel = "自动"
        self.ATemp = inpRegDataList[0]
        if coilsDataList[8] == '1':
            self.Dwind = "高风"
        if coilsDataList[9] == '1':
            self.Dwind = "中风"
        if coilsDataList[10] == '1':
            self.Dwind = "低风"
        if coilsDataList[11] == '1':
            self.Dwind = "微风"
        if coilsDataList[15] == '1':
            self.Dwind = "自动"
        # else:
        #     self.Dwind = "自动"
        self.eTemp = int(inpRegDataList[1])/2 - 20
        if coilsDataList[40] == '1':
            self.ErrorMessage = \
                self.ErrorMessage + "E0 相序错或缺相 ；"
        if coilsDataList[41] == '1':
            self.ErrorMessage = \
                self.ErrorMessage + "E1 通讯故障；"
        if coilsDataList[42] == '1':
            self.ErrorMessage = \
                self.ErrorMessage + "E2 T1传感器故障；"
        if coilsDataList[43] == '1':
            self.ErrorMessage = \
                self.ErrorMessage + "E3 T2A传感器故障；"
        if coilsDataList[44] == '1':
            self.ErrorMessage = \
                self.ErrorMessage + "E4 T2B传感器故障；"
        if coilsDataList[45] == '1':
            self.ErrorMessage = \
                self.ErrorMessage + "E5 T3或者T4或者数码压缩机排气温度传感器故障；"
        if coilsDataList[46] == '1':
            self.ErrorMessage = \
                self.ErrorMessage + "E6 过零检测错；"
        if coilsDataList[47] == '1':
            self.ErrorMessage = \
                self.ErrorMessage + "E7 EEPROM出错；"
        if coilsDataList[48] == '1':
            self.ErrorMessage = \
                self.ErrorMessage + "E8 风速检测失控；"
        if coilsDataList[49] == '1':
            self.ErrorMessage = \
                self.ErrorMessage + "E9 主板与显示板通；"
        if coilsDataList[50] == '1':
            self.ErrorMessage = \
                self.ErrorMessage + "EA 压缩机过流；"
        if coilsDataList[51] == '1':
            self.ErrorMessage = \
                self.ErrorMessage + "EB 变频模块保护；"
        if coilsDataList[52] == '1':
            self.ErrorMessage = \
                self.ErrorMessage + "EC 清新故障；"
        if coilsDataList[53] == '1':
            self.ErrorMessage = \
                self.ErrorMessage + "ED 室外故障保护；"
        if coilsDataList[54] == '1':
            self.ErrorMessage = \
                self.ErrorMessage + "EE 水位检测故障；"
        if coilsDataList[55] == '1':
            self.ErrorMessage = \
                self.ErrorMessage + "EF 其他故障；"
        if coilsDataList[72] == '1':
            self.ErrorMessage = \
                self.ErrorMessage + "0# 网络接口模块与主控板通讯故障；"
        if coilsDataList[73] == '1':
            self.ErrorMessage = \
                self.ErrorMessage + "1# 集中监控器与网络接口模块故障；"
        if coilsDataList[74] == '1':
            self.ErrorMessage = \
                self.ErrorMessage + "2# 集中监控器与功能模块通讯故障；"
        if coilsDataList[75] == '1':
            self.ErrorMessage = \
                self.ErrorMessage + "3# 集中监控器与计 算机（网关）通讯 故障；"
        if coilsDataList[76] == '1':
            self.ErrorMessage = \
                self.ErrorMessage + "4# 命令限制执行；"
        if coilsDataList[77] == '1':
            self.ErrorMessage = \
                self.ErrorMessage + "5# 命令超时，未执行；"
        if coilsDataList[78] == '1':
            self.ErrorMessage = \
                self.ErrorMessage + "6# 目的地址不存在；"
        if coilsDataList[79] == '1':
            self.ErrorMessage = \
                self.ErrorMessage + "7# 错误（不支持）的命令；"

    def compare_new_status(self, newSatatus):
        if isinstance(newSatatus, self.__class__):
            if self.Dwind != newSatatus.Dwind or \
                    self.FModel != newSatatus.FModel or \
                    self.Aoc != newSatatus.Aoc or \
                    self.ATemp != newSatatus.ATemp:
                return True
            else:
                return False
        else:
            return False


class ACStatusWater(Base):
    # 表的名字
    __tablename__ = 'StatusWater'
    # 表的结构
    id = Column(String(20), primary_key=True)
    DeviceAddress = Column(String(20))
    ATemp = Column(String(20))
    Aoc = Column(String(20))
    Dwind = Column(String(20))
    FModel = Column(String(20))
    HElec = Column(String(20))
    ErrorMessage = Column(String(20))
    Updatetime = Column(String(20))
    eTemp = Column(String(20))
    Aoctime = Column(String(20))

    def __str__(self):
        pass

    def __init__(self, id=None,
                 DeviceAddress=None, ATemp=None, Aoc=None,
                 Dwind=None, FModel=None, HElec=None, ErrorMessage=None,
                 Updatetime=None, Aoctime=None, eTemp=None
                 ):
        self.id = id
        self.ATemp = ATemp
        self.DeviceAddress = DeviceAddress
        self.Aoc = Aoc
        self.Dwind = Dwind
        self.FModel = FModel
        self.HElec = HElec
        self.Updatetime = Updatetime
        self.ErrorMessage = ErrorMessage
        self.Aoctime = Aoctime
        self.eTemp = eTemp


class ACInfo(Base):
    # 表的名字
    __tablename__ = 'Set_Tabel'
    # 表的结构
    DeviceID = Column(String(20), primary_key=True)
    DeviceAddress = Column(String(20))
    DevicePort = Column(String(20))

    def __init__(self, DeviceID=None, DeviceAddress=None, DevicePort=None):
        self.DeviceID = DeviceID
        self.DeviceAddress = DeviceAddress
        self.DevicePort = DevicePort


class ACControl(Base):
    # 表的名字
    __tablename__ = 'Control_Tabel'
    # 表的结构
    id = Column(Integer, Sequence('id_seq'), primary_key=True)
    Aoc = Column(String(20))
    ATemp = Column(String(20))
    DeviceID = Column(String(20))
    Dwind = Column(String(20))
    FModel = Column(String(20))
    HElec = Column(String(20))
    status = Column(String(20))
    Updatetime = Column(String(20))
    randomid = Column(String(30))

    def __init__(self,
                 randomid=0, Aoc=None, ATemp=None, DeviceID=0,
                 Dwind=None, FModel=None, HElec=None,
                 status=None, Updatetime=None,
                 ):
        self.randomid = randomid
        self.ATemp = ATemp
        self.Aoc = Aoc
        self.Dwind = Dwind
        self.FModel = FModel
        self.HElec = HElec
        self.Updatetime = Updatetime
        self.DeviceID = DeviceID
        self.status = status

    # 将json字符串转换为ACStatus，传入为一个json字符串
    @classmethod
    def Json2ModelList(self, obj):
        returnedList = []
        for row in obj:
            returnedList.append(
                ACControl(randomid=row['randomId'],
                          ATemp=row['atemp'].encode('gbk'),
                          Aoc=row['aoc'],
                          Dwind=row['dwind'],
                          FModel=row['fmodel'],
                          HElec=row['helec'],
                          Updatetime=u'-1',
                          DeviceID=row['deviceId'],
                          status=u'未发送'
                          )
            )
        return returnedList

    def set_ctrl_2_reg(self, acInfo):
        deviceAddress = acInfo.DeviceAddress
        deviceRegAddress = deviceAddress * 32
        deviceModelCtrl = 16
        deviceAOCCtrl = 0
        deviceModel = 16
        deviceWind = 128
        deviceTemp = 26
        if self.Aoc == "开机":
            deviceAOCCtrl = 128
            if self.FModel == "自动":
                deviceModelCtrl = 16
            if self.FModel == "制冷":
                deviceModelCtrl = 8
            if self.FModel == "制热":
                deviceModelCtrl = 4
            if self.FModel == "除湿":
                deviceModelCtrl = 2
            if self.FModel == "送风":
                deviceModelCtrl = 1
        else:
            deviceAOCCtrl = 0
            deviceModelCtrl = 0
        if int(self.ATemp) > 32 or int(self.ATemp) < 16:
            deviceTemp = '26'
        else:
            deviceTemp = self.ATemp
        if self.Dwind == "自动":
            deviceWind = 128
        if self.Dwind == "低风":
            deviceWind = 4
        if self.Dwind == "中风":
            deviceWind = 2
        if self.Dwind == "高风":
            deviceWind = 1

        rowUrl = "http://" + config.getConfig(section='address', key='gateWayIp') + "/ctrl.xml"
        timeStr = "?utsxxx=" + str(int(time.time()))
        deviceAddressStr = "&u=" + str(deviceAddress)
        fStr = "&f=16&"
        sStr = "s=" + str(int(deviceAddress) * 32 + 1)
        modelStr = "&c=3&p0=" + str(deviceModelCtrl + deviceAOCCtrl)
        windStr = "&p1=" + str(deviceWind)
        tempStr = "&p2=" + str(deviceTemp)
        restStr = "&p3=0&p4=0&p5=0&p6=0&p7=0"
        urlParam = timeStr + deviceAddressStr + fStr + sStr + modelStr + windStr + tempStr + restStr
        req = urllib.request.Request(url=rowUrl + urlParam)
        res = urllib.request.urlopen(req)
        res = res.read()
        statusData = str(xmlDecoder.get_xml_ret(res, 'ret')).split(',')
        self.Updatetime = time.strftime("%Y/%m/%d %H:%M:%S", time.localtime())
        if len(statusData) == 1 and statusData[0] == '0':
            self.status = "执行成功"
            return True
        else:
            self.status = "执行失败"
            return False


class ACSend(object):
    #
    # deviceId = None
    # atemp = None
    # aoc = None
    # dwind = None
    # helec = None
    # fmodel = None
    # etemp = None
    # errorMsg = None
    # aocTime = None
    # updateTime = None
    def __init__(self, ACStatusWater, ACInfo):
        # self.id=None
        # self.id=ACStatusWater.Id
        self.deviceId = ACInfo.DeviceID
        if ACStatusWater.ATemp is u'':
            self.atemp = '-99'
        else:
            self.atemp = ACStatusWater.ATemp
        self.aoc = ACStatusWater.Aoc
        self.dwind = ACStatusWater.Dwind
        self.helec = ACStatusWater.HElec
        self.fmodel = ACStatusWater.FModel
        if ACStatusWater.eTemp is u'':
            self.etemp = '-99'
        else:
            self.etemp = ACStatusWater.eTemp
        self.errorMsg = ACStatusWater.ErrorMessage
        self.updateTime = ACStatusWater.Updatetime
        self.aocTime = ACStatusWater.Aoctime
        self.id = ACStatusWater.id
        # def encoding(self):

        # self.status=None
        # self.sendinstance={"deviceId":self.deviceId,
        #                "atemp": self.atemp,
        #                "aoc": self.aoc,
        #                "dwind": self.dwind,
        #                "helec": self.helec,
        #                "fmodel": self.fmodel,
        #                "etemp": self.etemp,
        #                "errorMsg": self.errorMsg,
        #                "aocTime": self.aocTime,
        #                "updateTime": self.updateTime,
        #                }


class ACCrlSend(object):
    def __init__(self, ACControl):
        self.randomId = ACControl.randomid
        self.deviceId = ACControl.DeviceID
        self.atemp = ACControl.ATemp
        self.aoc = ACControl.Aoc
        self.dwind = ACControl.Dwind
        self.fmodel = ACControl.FModel
        self.helec = ACControl.HElec
        self.status = ACControl.status
        self.updateTime = ACControl.Updatetime
        self.id = ACControl.id


class Meta(object):
    def __init__(self, success=None, message=None):
        self.success = success
        self.message = message

    def isSuccess(self):
        return self.success

    def getMessage(self):
        return self.message


class Response(object):
    def __init__(self, inmeta=Meta(), indata=None):
        # self.meta.success=inmeta['success']
        # self.meta.message=inmeta['message']
        self.meta = inmeta
        self.data = indata

    def success(self, data=None):
        self.meta = Meta(True, 'OK')
        if data is not None:
            self.data = data
        return self

    def failure(self, failmessage=None):
        if failmessage is not None:
            self.meta = Meta(False, message=failmessage)
        else:
            self.meta = Meta(False, message='error')
        return self

    @staticmethod
    def Json2ModelList(obj):
        '''
        解析传入的response数据结构体
        :param obj: json型的response数据
        :return: 解析之后的response实例
        '''
        return Response(inmeta=Meta(obj['meta']['success'], obj['meta']['message']),
                        indata=obj['data'])
